﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Engine.Material.Shader;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Engine.Light;

namespace Etapa1.Screens
{
    public class DeepShader : IShader
    {
        private Vector3 lampPos;
        private Matrix LampView;
        private Matrix LampProj;

        public override void Attach(Engine.Cameras.ICamera cam)
        {            
            foreach (ILight item in lights)
            {
                if (item is SimpleLight)
                {
                    SimpleLight sl = item as SimpleLight;
                    this.lampPos = sl.Position;
                    this.LampProj = sl.Project;
                    this.LampView = sl.View;
                }
            }

            _shader.Parameters["World"].SetValue(obj.getWorldMatrix());
            _shader.Parameters["Lamp0Pos"].SetValue(lampPos);
            _shader.Parameters["LampView"].SetValue(LampView);
            _shader.Parameters["LampProj"].SetValue(LampProj);
            //_shader.Parameters["Lamp0Pos"].SetValue(cam.Position);
            //_shader.Parameters["LampView"].SetValue(cam.View);
            //_shader.Parameters["LampProj"].SetValue(cam.Projection);
        }
        public override void Initialize(Engine.EngineStuff es)
        {
            this._shader = es.Content.Load<Effect>("..\\Content\\Effects\\deep");
            base.Initialize(es);
        }

        public override void Draw(Engine.Modelo.IModelo modelo, Engine.SceneControl.Scene.IRenderHelper render, Engine.Cameras.ICamera cam)
        {
            
            ModelMesh[] sampleMesh = modelo.getModelMeshes(0);

            if (sampleMesh == null)
                return;

            //if (boneTransforms == null || boneCount != sampleMesh.Bones.Count)
            //{
            //    boneTransforms = new Matrix[sampleMesh.Bones.Count];
            //    boneCount = sampleMesh.Bones.Count;
            //}
            boneTransforms = modelo.getBonesTransformation(0);
            boneCount = boneTransforms.Length;
            //sampleMesh.CopyAbsoluteBoneTransformsTo(boneTransforms);
            //our sample meshes only contain a single part, so we don't need to bother
            //looping over the ModelMesh and ModelMeshPart collections. If the meshes
            //were more complex, we would repeat all the following code for each part
            //ModelMesh mesh = sampleMesh.Meshes[0];
            foreach (ModelMesh mesh in sampleMesh)
            {

                ModelMeshPart meshPart = mesh.MeshParts[0];

                //set the vertex source to the mesh's vertex buffer
                _graphics.GraphicsDevice.Vertices[0].SetSource(
                    mesh.VertexBuffer, meshPart.StreamOffset, meshPart.VertexStride);

                //set the vertex delclaration
                _graphics.GraphicsDevice.VertexDeclaration = meshPart.VertexDeclaration;

                //set the current index buffer to the sample mesh's index buffer
                _graphics.GraphicsDevice.Indices = mesh.IndexBuffer;

                // set the current technique based on the user selection
                _shader.CurrentTechnique = _shader.Techniques[activeTechnique];

                //at this point' we're ready to begin drawing
                //To start using any effect, you must call Effect.Begin
                //to start using the current technique (set in Load_graphicsContent)
                _shader.Begin(SaveStateMode.None);
                Matrix world = _shader.Parameters["World"].GetValueMatrix();
                world = Matrix.Multiply(world, boneTransforms[mesh.ParentBone.Index]);
                _shader.Parameters["World"].SetValue(world);

                //now we loop through the passes in the teqnique, drawing each
                //one in order
                for (int i = 0; i < _shader.CurrentTechnique.Passes.Count; i++)
                {
                    //EffectPass.Begin will update the device to
                    //begin using the state information defined in the current pass
                    _shader.CurrentTechnique.Passes[i].Begin();

                    //sampleMesh contains all of the information required to draw
                    //the current mesh
                    _graphics.GraphicsDevice.DrawIndexedPrimitives(
                        PrimitiveType.TriangleList, meshPart.BaseVertex, 0,
                        meshPart.NumVertices, meshPart.StartIndex, meshPart.PrimitiveCount);

                    //EffectPass.End must be called when the effect is no longer needed
                    _shader.CurrentTechnique.Passes[i].End();
                }

                //Likewise, Effect.End will end the current technique
                _shader.End();


            }
        }
    }
}
